package com.online.questionnaire.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.online.questionnaire.common.ErrorCode;
import com.online.questionnaire.exception.BusinessException;
import com.online.questionnaire.mapper.AnswerMapper;
import com.online.questionnaire.mapper.SurveysMapper;
import com.online.questionnaire.model.Answer;
import com.online.questionnaire.model.SurveySubmit;
import com.online.questionnaire.model.Surveys;
import com.online.questionnaire.model.User;
import com.online.questionnaire.model.dto.AnswerSheet;
import com.online.questionnaire.model.dto.SubmitSurveyDTO;
import com.online.questionnaire.model.dto.QuestionsDTO;
import com.online.questionnaire.model.dto.SurveysDTO;
import com.online.questionnaire.service.*;
import com.online.questionnaire.mapper.SurveySubmitMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
* @author 27701
* @description 针对表【survey_submit(提交记录 可查看每次提交详情)】的数据库操作Service实现
* @createDate 2025-02-22 23:42:17
*/
@Service
public class SurveySubmitServiceImpl extends ServiceImpl<SurveySubmitMapper, SurveySubmit>
    implements SurveySubmitService{

    @Resource
    private AnswerMapper answerMapper;
    @Resource
    private SurveySubmitMapper surveySubmitMapper;
    @Resource
    private SurveysService surveysService;
    @Resource
    private QuestionsService questionsService;
    @Resource
    private OptionsService optionsService;
    @Resource
    private UserService userService;
    @Autowired
    private SurveysMapper surveysMapper;

    @Override
    @Transactional
    public boolean submitAnswer(SubmitSurveyDTO submitSurveyDTO, HttpServletRequest request) {
        Long surveyId = submitSurveyDTO.getSurveyId();
        Long userId = submitSurveyDTO.getUserId();
        List<Answer> answerList = submitSurveyDTO.getAnswerList();
        if (answerList == null || answerList.isEmpty()){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"提交的答案为空！");
        }
        //检查问卷是否允许提交(状态就开放并且在有效范围内)
        Surveys surveys = surveysService.getById(surveyId);
        if (surveys == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"问卷不存在");
        }
        if (surveys.getStatus() != 1){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"问卷未发布");
        }
        //为设置起始时间 视为无限制
        if (surveys.getStarttime() != null && surveys.getStarttime().getTime() > System.currentTimeMillis()){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"问卷未开始");
        }
        if ( surveys.getEndtime() != null && surveys.getEndtime().getTime() < System.currentTimeMillis()){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"问卷已结束");
        }

        //检查用户是否重复提交  为开启登录校验的 判断浏览器指纹是否重复  开启登录校验判断用户id
        if (surveys.getIsRepeated() == 0){
            if (surveys.getIsLogin() == 1){
                User submitUser = userService.getLoginUser(request);
                if (submitUser == null){
                    throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR ,"请先登录");
                }
                QueryWrapper<SurveySubmit> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("surveyId",surveyId);
                queryWrapper.eq("userId",submitUser.getId());
                if (surveySubmitMapper.selectCount(queryWrapper) > 0){
                    throw new BusinessException(ErrorCode.PARAMS_ERROR,"请勿重复提交");
                }
            }else{
                QueryWrapper<SurveySubmit> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("surveyId",surveyId);
                queryWrapper.eq("fingerprint",submitSurveyDTO.getFingerprint());
                if (surveySubmitMapper.selectCount(queryWrapper) > 0){
                    throw new BusinessException(ErrorCode.PARAMS_ERROR,"请勿重复提交");
                }
            }
        }


        //先保存 一次提交
        SurveySubmit surveySubmit = new SurveySubmit();
        surveySubmit.setFingerprint(submitSurveyDTO.getFingerprint());
        surveySubmit.setSurveyId(surveyId);
        surveySubmit.setSubmitTime(submitSurveyDTO.getSubmitTime());
        //如果开启登录校验 设置用户Id 同时校验是否登录
        if (surveys.getIsLogin() == 1){
            User loginUser = userService.getLoginUser(request);
            if (loginUser == null){
                throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR ,"请先登录");
            }
            surveySubmit.setUserId(loginUser.getId());
        }

        int insert1 = surveySubmitMapper.insert(surveySubmit);
        if (insert1 <= 0){
            throw new BusinessException(ErrorCode.OPERATION_ERROR,"提交创建失败！");
        }
        Long submitId = surveySubmit.getId();

        //遍历存储
        for (Answer answer : answerList) {
            if (answer.getQuestionId() == null || answer.getType() == null){
                throw new BusinessException(ErrorCode.PARAMS_ERROR,"参数错误");
            }
            answer.setSubmitId(submitId);
            QuestionsDTO questionsDTO = questionsService.getDTOById(answer.getQuestionId());
            //单选
            if (questionsDTO.getType() == 0){
                //判断是否必填
                if (questionsDTO.getRequired() == 1 && StringUtils.isBlank(answer.getValue())){
                    throw new BusinessException(ErrorCode.PARAMS_ERROR,questionsDTO.getId() + "题目 value为空");
                }
                //查找value一致的选项 获取id 使用stream
                questionsDTO.getOptions().stream()
                        .filter(options -> options.getValue().equals(answer.getValue()))
                        .findFirst()
                        .ifPresentOrElse(options -> {
                            Answer insert = new Answer();
                            BeanUtils.copyProperties(answer,insert);
                            insert.setId(null);
                            insert.setSurveyId(surveyId);
                            //找到 设置optionid
                            insert.setOptionId(options.getId());
                            answerMapper.insert(insert);
                        }, () -> {
                            //判断是否必填
                            if (questionsDTO.getRequired() == 1){
                                throw new BusinessException(ErrorCode.PARAMS_ERROR,questionsDTO.getId() + "题目 value不存在");
                            }
                        });
            }

            //多选 value为JSON数组
            if (questionsDTO.getType() == 1){
                List<String> list = null;
                //转为数组
                try {
                    list = JSONUtil.toList(answer.getValue(), String.class);
                } catch (Exception e) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR,questionsDTO.getId() + "题目 value的json格式错误");
                }

                if (questionsDTO.getRequired() == 1 && list.isEmpty()){
                    throw new BusinessException(ErrorCode.PARAMS_ERROR,questionsDTO.getId() + "题目 value为空");
                }
                //循环选择的选项 每条选项插入一行
                for (String s : list) {
                    questionsDTO.getOptions().stream()
                            .filter(options -> options.getValue().equals(s))
                            .findFirst()
                            .ifPresentOrElse(options -> {
                                Answer insert = new Answer();
                                BeanUtils.copyProperties(answer,insert);
                                insert.setId(null);
                                //找到 设置optionid
                                insert.setOptionId(options.getId());
                                insert.setSurveyId(surveyId);
                                insert.setValue(s);
                                answerMapper.insert(insert);
                            }, () -> {
                                //判断是否必填
                                if (questionsDTO.getRequired() == 1){
                                    throw new BusinessException(ErrorCode.PARAMS_ERROR,questionsDTO.getId() + "题目 value不存在");
                                }
                            });
                }
            }

            //填空与时间选择
            if (questionsDTO.getType() == 2 || questionsDTO.getType() == 3 ||
                    questionsDTO.getType() == 5 ){
                if (questionsDTO.getRequired() == 1 && StringUtils.isBlank(answer.getValue())){
                    throw new BusinessException(ErrorCode.PARAMS_ERROR,questionsDTO.getId() + "题目 value为空");
                }
                answer.setSurveyId(surveyId);
                answerMapper.insert(answer);
            }

            //评分
            if (questionsDTO.getType() == 4){
                if (questionsDTO.getRequired() == 1 && answer.getValue() == null){
                    throw new BusinessException(ErrorCode.PARAMS_ERROR,questionsDTO.getId() + "题目 value为空");
                }
                answer.setSurveyId(surveyId);
                answerMapper.insert(answer);
            }


        }
        return true;
    }

    @Override
    public Long getSubmitNum(Long surveyId) {

        QueryWrapper<SurveySubmit> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("surveyId",surveyId);
        return surveySubmitMapper.selectCount(queryWrapper);
    }

    @Override
    public AnswerSheet getAnswerSheet(Long submitId) {
        //查询提交记录是否存在
        SurveySubmit surveySubmit = surveySubmitMapper.selectById(submitId);
        if (surveySubmit == null){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR,"提交记录不存在");
        }
        AnswerSheet answerSheet = new AnswerSheet();
        answerSheet.setSurveyId(surveySubmit.getSurveyId());
        answerSheet.setSubmitId(submitId);

        //查询该提交下的所有答案
        List<Answer> answersSheetBySubmitId = answerMapper.getAnswersSheetBySubmitId(submitId);
        if (answersSheetBySubmitId.isEmpty()){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR,"提交记录下没有答案");
        }
        for (Answer answer : answersSheetBySubmitId){
            //单独处理 多选
            if (answer.getType() == 1){
                if (StringUtils.isBlank(answer.getValue())){
                    answer.setValue("[]");
                }else{
                    answer.setValue("[" + answer.getValue() +"]");
                }
            }
        }

        answerSheet.setList(answersSheetBySubmitId);
        return answerSheet;
    }

    @Override
    public SurveysDTO getSurveysDTOAnswer(Long submitId) {
        AnswerSheet answerSheet = this.getAnswerSheet(submitId);
        SurveysDTO surveysDTO = surveysService.getDTOById(answerSheet.getSurveyId());

        //answerSheet中的将value设置到surveysDTO
        for (QuestionsDTO questionsDTO : surveysDTO.getQuestions()){
            for (Answer answer : answerSheet.getList()){
                if (answer.getQuestionId().equals(questionsDTO.getId())){
                    questionsDTO.setValue(answer.getValue());
                }
            }
        }
        return surveysDTO;
    }

}




